﻿using System.ComponentModel;
using Inspire.Interfaces;
using System;
using System.Collections.Generic;
using System.Data.Objects.DataClasses;
using Inspire.Classes.Business;

namespace Inspire.Entities
{
    public partial class Patron : Person, IEntityWithRelationships
    {
        private PatronBusiness _patronBusiness;

        /// <summary>
        /// Constructor.
        /// </summary>
        public Patron()
        {
            // Get a reference to the PatronBusiness object.
            this._patronBusiness = PatronBusiness.GetPatronBusiness();
        }

        #region Allow Translation of Patron Objects into the Parent IDs

        /// <summary>
        /// This property translates the Patron object provided to it into an ID number that is actually stored in the database.
        /// I tried to use foreign key relationships in the Entity Diagram tool, but could not get them to work correctly.
        /// </summary>
        public Patron Parent1
        {
            get
            {
                return this._patronBusiness.GetPatron(this._ParentId);
            }
            set
            {
                if (value != null)
                {
                    this._ParentId = ((Patron)value).Id;
                }
                else
                {
                    this._ParentId = null;
                }
            }
        }

        /// <summary>
        /// This property translates the Patron object provided to it into an ID number that is actually stored in the database.
        /// I tried to use foreign key relatinships in the Entity Diagram tool, but could not get them to work correctly.
        /// </summary>
        public Patron Parent2
        {
            get
            {
                return this._patronBusiness.GetPatron(this._ParentId2);
            }
            set
            {
                if (value != null)
                {
                    this._ParentId2 = ((Patron)value).Id;
                }
                else
                {
                    this._ParentId2 = null;
                }
            }
        }

        #endregion

        #region Partial implementation of Property Event Handlers

        /// <summary>
        /// Event handler for changing of the Company property.
        /// </summary>
        /// <param name="value">(string) The new value of the Company property.</param>
        partial void  OnCompanyChanging(string value)
        {
            // Get a Validation Message if it fails validation
            string errorMessage = this.ValidateCompany(value);

            if (errorMessage.Length > 0)
            {
                if (!(this._errors.ContainsKey("Company")))
                {
                    this._errors.Add("Company", errorMessage);
                }
            }
            else
            {
                this._errors.Remove("Company");
            }
        }

        /// <summary>
        /// Event handler for changing of the School property.
        /// </summary>
        /// <param name="value">(string) The new value of the School property.</param>
        partial void OnSchoolChanging(string value)
        {
            // Get a Validation Message if it fails validation
            string errorMessage = this.ValidateSchool(value);

            if (errorMessage.Length > 0)
            {
                if (!(this._errors.ContainsKey("School")))
                {
                    this._errors.Add("School", errorMessage);
                }
            }
            else
            {
                this._errors.Remove("School");
            }
        }

        #endregion

        #region IValidation Members

        /// <summary>
        /// Return a validation message for Company
        /// </summary>
        /// <param name="value">The value to be validated</param>
        /// <returns>(string) Error message</returns>
        protected string ValidateCompany(string value)
        {
            if (value != null && value.Length > 100)
            {
                return "Company has a max length of 100 characters.";
            }
            return String.Empty;
        }

        /// <summary>
        /// Return a validation message for School
        /// </summary>
        /// <param name="value">The value to be validated</param>
        /// <returns>(string) Error message</returns>
        protected string ValidateSchool(string value)
        {
            if (value != null && value.Length > 100)
            {
                return "School has a max length of 100 characters.";
            }
            return String.Empty;
        }

        /// <summary>
        /// Validate all fields
        /// </summary>
        /// <returns>bool True if no errors were found; false, otherwise.</returns>
        public override bool Validate()
        {
            // Validate the DataContext as a Person entity first, then as a Patron
            bool isValidated = base.Validate();

            // Store message for Validation
            string message;

            #region Validate fields and add message messages to _errors

            // Company
            message = ValidateCompany(this.Company);
            if (message.Length > 0)
            {
                this._errors["Company"] = message;
                isValidated = false;
            }

            // School
            message = ValidateSchool(this.School);
            if (message.Length > 0)
            {
                this._errors["School"] = message;
                isValidated = false;
            }

            #endregion

            return isValidated;
        }

        #endregion

        /// <summary>
        /// Provides a Shallow Copy of this object.
        /// </summary>
        /// <returns>A Shallow Copy of the original Patron object.</returns>
        public Patron ShallowCopy()
        {
            return (Patron)this.MemberwiseClone();
        }

        /// <summary>
        /// Resets all values to their default except the circulations property. This method does not commit the changes to the database.
        /// </summary>
        public void Reset()
        {
            // Reset the Person Fields
            base.Reset();

            // Reset the Patron Fields
            this.Company = "";
            this.StudentId = "";
            this.StudentGrade = "";
            this.ParentId = null;
            this.ParentId2 = null;
            this.School = "";
            this.ReadingLevel = "";

            // Clear Error Messages Regarding the Empty Fields
            this._errors.Clear();
        }

        /// <summary>
        /// Override the ToString() method to simplify the use of this object as an item in a list.
        /// </summary>
        /// <returns>The last name and first name of this patron concatenated together by a comma.</returns>
        public override string ToString()
        {
            return this.LastName + ", " + this.FirstName + " " + this.MiddleName + " -- " + this.City + ", " + this.State;
        }
    }
}
